/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Audio
 * @{
 *
 * @brief Audio模块接口定义
 *
 * 音频接口涉及自定义类型、驱动加载接口、驱动适配器接口、音频播放（render）接口、音频录音（capture）接口等
 *
 * @since 1.0
 * @version 1.0
 */

/**
 * @file audio_render.h
 *
 * @brief Audio播放的接口定义文件
 *
 * @since 1.0
 * @version 1.0
 */

#ifndef AUDIO_RENDER_H
#define AUDIO_RENDER_H

#include "audio_types.h"
#include "audio_control.h"
#include "audio_attribute.h"
#include "audio_scene.h"
#include "audio_volume.h"

/**
 * @brief AudioRender音频播放接口
 *
 * 提供音频播放支持的驱动能力，包括音频控制、音频属性、音频场景、音频音量、获取硬件延迟时间、播放音频帧数据（render frame）等
 *
 * @see AudioControl
 * @see AudioAttribute
 * @see AudioScene
 * @see AudioVolume
 * @since 1.0
 * @version 1.0
 */
struct AudioRender {
    /**
     * @brief 音频控制能力接口，详情参考{@link AudioControl}
     */
    struct AudioControl control;

    /**
     * @brief 音频属性能力接口，详情参考{@link AudioAttribute}
     */
    struct AudioAttribute attr;

    /**
     * @brief 音频场景能力接口，详情参考{@link AudioScene}
     */
    struct AudioScene scene;

    /**
     * @brief 音频音量能力接口，详情参考{@link AudioVolume}
     */
    struct AudioVolume volume;

    /**
     * @brief 获取音频硬件驱动估计的延迟时间
     *
     * @param render 待操作的音频播放接口对象
     * @param ms 获取的延迟时间（单位：毫秒）保存到ms中
     * @return 成功返回值0，失败返回负值
     */
    int32_t (*GetLatency)(struct AudioRender *render, uint32_t *ms);

    /**
     * @brief 往音频驱动中播放（render）一帧输出数据（放音，音频下行数据）
     *
     * @param render 待操作的音频播放接口对象
     * @param frame 待写入的输出数据的音频frame
     * @param requestBytes 待写入的输出数据的音频frame大小（字节数）
     * @param replyBytes 实际写入的音频数据长度（字节数），获取后保存到replyBytes中
     * @return 成功返回值0，失败返回负值
     */
    int32_t (*RenderFrame)(struct AudioRender *render, const void *frame, uint64_t requestBytes, uint64_t *replyBytes);

    /**
     * @brief 获取音频输出帧数的上一次计数
     *
     * @param render 待操作的音频播放接口对象
     * @param frames 获取的音频帧计数保存到frames中
     * @param time 获取的关联时间戳保存到time中
     * @return 成功返回值0，失败返回负值
     * @see RenderFrame
     */
    int32_t (*GetRenderPosition)(struct AudioRender *render, uint64_t *frames, struct AudioTimeStamp *time);

    /**
     * @brief 设置一个音频的播放速度
     *
     * @param render 待操作的音频播放接口对象
     * @param speed 待设置的播放速度
     * @return 成功返回值0，失败返回负值
     * @see GetRenderSpeed
     */
    int32_t (*SetRenderSpeed)(struct AudioRender *render, float speed);

    /**
     * @brief 获取一个音频当前的播放速度
     *
     * @param render 待操作的音频播放接口对象
     * @param speed 获取的播放速度保存到speed中
     * @return 成功返回值0，失败返回负值
     * @see SetRenderSpeed
     */
    int32_t (*GetRenderSpeed)(struct AudioRender *render, float *speed);

    /**
     * @brief 设置音频播放的通道模式
     *
     * @param render 待操作的音频播放接口对象
     * @param speed 待设置的通道模式
     * @return 成功返回值0，失败返回负值
     * @see GetChannelMode
     */
    int32_t (*SetChannelMode)(struct AudioRender *render, enum AudioChannelMode mode);

    /**
     * @brief 获取音频播放当前的通道模式
     *
     * @param render 待操作的音频播放接口对象
     * @param mode 获取的通道模式保存到mode中
     * @return 成功返回值0，失败返回负值
     * @see SetChannelMode
     */
    int32_t (*GetChannelMode)(struct AudioRender *render, enum AudioChannelMode *mode);

    /**
     * @brief 注册音频回调函数，用于放音过程中缓冲区数据写、DrainBuffer完成通知
     * @param render 待操作的音频播放接口对象
     * @param callback 注册的回调函数
     * @param cookie 回调函数的入参
     * @return 成功返回值0，失败返回负值
     * @see RegCallback
     */
    int32_t (*RegCallback)(struct AudioRender *render, RenderCallback callback, void* cookie);

    /**
     * @brief 排空缓冲区中的数据
     *
     * @param render 待操作的音频播放接口对象
     * @param type DrainBuffer的操作类型，详情请参考{@link AudioDrainNotifyType}
     * @return 成功返回值0，失败返回负值
     * @see RegCallback
     */
    int32_t (*DrainBuffer)(struct AudioRender *render, enum AudioDrainNotifyType *type);
};
#endif /* AUDIO_RENDER_H */
/** @} */
